'''
对于给定的一组任务和一组车辆以及路径长度，作出最佳的任务分配决策

对外接口：
- distribute_task(tasks, aivs, nowtime, distance_matrix) -> InsTask
'''

from common import InsTask
from munkres import Munkres

def distribute_task(tasks, aivs, nowtime, distance_matrix) -> list:
    '''
    会改变传入的 aivs 列表，如果不希望改变，则需要 clone 一下
    '''
    instructions = []
    distances = []
    # 依次选择每个任务
    for aiv in aivs:
        distance = []
        for task in tasks:
            distance.append(distance_matrix.distance_get(aiv['position'], task.start_pos))
        distances.append(distance)
    m = Munkres()
    
    # 如果 distances 为空的话，Munkres().compute(distances) 会报错
    if not distances:
        return instructions

    km_result = m.compute(distances)
    for aiv_index, task_index in km_result:
        # aiv 并不需要 distance 键值对了
        # aiv['distance'] = distances[aiv_index][task_index]
        # 计算到目的地的距离
        full_distance = distance_matrix.distance_get(aivs[aiv_index]['position'], tasks[task_index].destination)

        instructions.append(InsTask(aivs[aiv_index], tasks[task_index], full_distance))

    return instructions
